//
//  YCSegmentPageVC.m
//  YCSegmentPage
//
//  Created by tangkexiong on 16/3/14.
//  Copyright © 2016年 tangkexiong. All rights reserved.
//

#import "YCSegmentPageVC.h"

#pragma mark - YCSegmentPageVCHeaderView

@implementation YCSegmentPageVCHeaderView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    if (self) {
        [self _initConfig];
    }
    
    return self;
}

- (void)_initConfig {
    self.backgroundColor = [UIColor whiteColor];
    
    _imgView = [[UIImageView alloc] init];
    _imgView.contentMode = UIViewContentModeScaleAspectFill;
    _imgView.clipsToBounds = YES;
    [self addSubview:_imgView];
    
    _imgView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_imgView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_imgView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_imgView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_imgView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
}

@end

#pragma mark - YCSegmentPageVCSegmentView

@interface YCSegmentPageVCSegmentView () {
    UIView *_lineView;
}

@end

@implementation YCSegmentPageVCSegmentView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    if (self) {
        [self _initConfig];
    }
    
    return self;
}

- (void)_initConfig {
    self.backgroundColor = [UIColor whiteColor];
    
    _segmentCtrl = [[UISegmentedControl alloc] init];
    _segmentCtrl.selectedSegmentIndex = 0;
    [self addSubview:_segmentCtrl];
    
    _segmentCtrl.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_segmentCtrl attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:8.f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_segmentCtrl attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:8.f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_segmentCtrl attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:-8.f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_segmentCtrl attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:-8.f]];
    
    _lineView = [[UIView alloc] init];
    _lineView.backgroundColor = [UIColor blackColor];
    [self addSubview:_lineView];
    
    _lineView.translatesAutoresizingMaskIntoConstraints = NO;
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_lineView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0.f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_lineView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:0.f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:_lineView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:0.f]];
    [_lineView addConstraint:[NSLayoutConstraint constraintWithItem:_lineView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:0.5f]];
}

@end

#pragma mark - YCSegmentPageVC

const void*_YCSEGMENTPAGEVC_CURPAGE_SCROLLVVIEWOFFSET = &_YCSEGMENTPAGEVC_CURPAGE_SCROLLVVIEWOFFSET;

#define kDefaultSegmentViewHegiht 44.f
#define kDefaultHeaderViewHeight 200.f
#define kDefaultSegmentViewMinTopInsetLandscape 32.f
#define kDefaultSegmentViewMinTopInsetPortrait 64.f

@interface YCSegmentPageVC () {
    NSLayoutConstraint *_constraintHeaderViewHeight;

    NSInteger _segmentCount;
    CGFloat _segmentViewMinTopOffset;
    CGFloat _segmentViewMaxTopOffset;
    CGFloat _segmentViewHeight;
    
    UIScrollView *_curScrollView;
}

@end

@implementation YCSegmentPageVC

#pragma mark - UIViewController

- (instancetype)init {
    self = [super init];
    
    if (self) {
        [self _initConfig];
    }
    
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        [self _initConfig];
    }
    
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    
    [self _initConfig];
}

- (void)_initConfig {
    _segmentCount = 0;
}

- (void)_initConfigSegmentViewMinTopInset {
    if ([_dataSource respondsToSelector:@selector(minTopOffsetOfSegmentViewInSegmentPageVC:whileOrientation:)]) {
        _segmentViewMinTopOffset = [_dataSource minTopOffsetOfSegmentViewInSegmentPageVC:self whileOrientation:self.interfaceOrientation];
    } else {
        if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
            _segmentViewMinTopOffset = kDefaultSegmentViewMinTopInsetLandscape;
        } else {
            _segmentViewMinTopOffset = kDefaultSegmentViewMinTopInsetPortrait;
        }
    }
}

- (void)_initConfigSegmentViewMaxTopInset {
    if ([_dataSource respondsToSelector:@selector(heightOfHeaderViewInSegmentPageVC:)]) {
        _segmentViewMaxTopOffset = [_dataSource heightOfHeaderViewInSegmentPageVC:self];
    } else {
        _segmentViewMaxTopOffset = kDefaultHeaderViewHeight;
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self _initConfigSegmentViewMinTopInset];
    [self _initConfigSegmentViewMaxTopInset];
    
    [self _configView];
    
    self.automaticallyAdjustsScrollViewInsets = NO;
}

- (void)_configView {
    self.view.translatesAutoresizingMaskIntoConstraints = NO;
    
    /////////////// 设置headerView
    
    if ([_dataSource respondsToSelector:@selector(headerViewInSegmentPageVC:)]) {
        _headerView = [_dataSource headerViewInSegmentPageVC:self];
    } else {
        _headerView = [[YCSegmentPageVCHeaderView alloc] init];
    }
    [self.view addSubview:_headerView];
    // 因为要使用autolayout
    _headerView.translatesAutoresizingMaskIntoConstraints = NO;
    // 设置约束
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_headerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_headerView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_headerView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
    _constraintHeaderViewHeight = [NSLayoutConstraint constraintWithItem:_headerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:_segmentViewMaxTopOffset];
    [_headerView addConstraint:_constraintHeaderViewHeight];
    
    /////////////// 设置segmentView
    if ([_dataSource respondsToSelector:@selector(segmentViewInSegmentPageVC:)] ) {
        _segmentView = [_dataSource segmentViewInSegmentPageVC:self];
    } else {
        _segmentView = [[YCSegmentPageVCSegmentView alloc] init];
    }
    [_segmentView.segmentCtrl addTarget:self action:@selector(segmentCtrlDidChange:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:_segmentView];
    if ([_dataSource respondsToSelector:@selector(numberOfSegmentsInSegmentPageVC:)]) {
        _segmentCount = [_dataSource numberOfSegmentsInSegmentPageVC:self];
    }
    for (int i = 0; i < _segmentCount; i++) {
        NSString *title = @"";
        if ([_dataSource respondsToSelector:@selector(titleOfSegmentInSegmentPageVC:atIndex:)]) {
            title = [_dataSource titleOfSegmentInSegmentPageVC:self atIndex:i];
        }
        [_segmentView.segmentCtrl insertSegmentWithTitle:title atIndex:i animated:NO];
    }
    // 因为要使用autoLayout
    _segmentView.translatesAutoresizingMaskIntoConstraints = NO;
    // 设置约束
    _segmentViewHeight = kDefaultSegmentViewHegiht;
    if ([_dataSource respondsToSelector:@selector(heightOfSegmentViewInSegmentPageVC:)]) {
        _segmentViewHeight = [_dataSource heightOfSegmentViewInSegmentPageVC:self];
    }
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_segmentView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_segmentView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_segmentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_headerView attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
    [_segmentView addConstraint:[NSLayoutConstraint constraintWithItem:_segmentView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:_segmentViewHeight]];
    // 默认选中第一个
    [_segmentView.segmentCtrl setSelectedSegmentIndex:0];
    [self segmentCtrlDidChange:_segmentView.segmentCtrl];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - Orientation

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self _initConfigSegmentViewMinTopInset];
}

#pragma mark - Observer

- (void)addObserverForScrollView:(UIScrollView *)scrollView {
    if (scrollView) {
        [scrollView addObserver:self forKeyPath:NSStringFromSelector(@selector(contentOffset)) options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:&_YCSEGMENTPAGEVC_CURPAGE_SCROLLVVIEWOFFSET];
    }
}

- (void)removeObserverForScrollView:(UIScrollView *)scrollView {
    if (scrollView) {
        @try {
            [scrollView removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentOffset))];
        }
        @catch (NSException *exception) {
            NSLog(@"%@", exception);
        }
        @finally {
            
        }
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if (context == _YCSEGMENTPAGEVC_CURPAGE_SCROLLVVIEWOFFSET) {
        CGFloat offsetY = [change[NSKeyValueChangeNewKey] CGPointValue].y;
        CGFloat oldOffsetY = [change[NSKeyValueChangeOldKey] CGPointValue].y;
        CGFloat deltaOfOffsetY = offsetY - oldOffsetY;
        
        if (deltaOfOffsetY > 0) {
            // 当滑动是向上滑动时
            // 跟随移动的偏移量进行变化
            // NOTE:直接相减有可能constant会变成负数，进而被系统强行移除，导致header悬停的位置错乱或者crash
            if (_constraintHeaderViewHeight.constant - deltaOfOffsetY <= 0) {
                _constraintHeaderViewHeight.constant = _segmentViewMinTopOffset;
            } else {
                _constraintHeaderViewHeight.constant -= deltaOfOffsetY;
            }
            // 如果到达顶部固定区域，那么不继续滑动
            if (_constraintHeaderViewHeight.constant <= _segmentViewMinTopOffset) {
                _constraintHeaderViewHeight.constant = _segmentViewMinTopOffset;
            }
        } else {
            // 当向下滑动时
            // 如果列表已经滚动到屏幕上方
            // 那么保持顶部栏在顶部
            if (offsetY > 0) {
                if (_constraintHeaderViewHeight.constant <= _segmentViewMinTopOffset) {
                    _constraintHeaderViewHeight.constant = _segmentViewMinTopOffset;
                }
            } else {
                CGFloat offsetYWithSegment = offsetY + _segmentViewHeight;
                // 如果列表顶部已经进入屏幕
                // 如果顶部栏已经到达底部
                if (_constraintHeaderViewHeight.constant >= _segmentViewMaxTopOffset) {
                    // 如果当前列表滚到了顶部栏的底部
                    // 那么顶部栏继续跟随变大，否这保持不变
                    if (-offsetYWithSegment > _segmentViewMaxTopOffset) {
                        _constraintHeaderViewHeight.constant = -offsetYWithSegment;
                    } else {
                        _constraintHeaderViewHeight.constant = _segmentViewMaxTopOffset;
                    }
                } else {
                    // 在顶部拦未到达底部的情况下
                    // 如果列表还没滚动到顶部栏底部，那么什么都不做
                    // 如果已经到达顶部栏底部，那么顶部栏跟随滚动
                    if (_constraintHeaderViewHeight.constant < -offsetYWithSegment) {
                        _constraintHeaderViewHeight.constant -= deltaOfOffsetY;
                    }
                }
            }
        }
    }
    // 通知偏移发生改变
    if ([_delegate respondsToSelector:@selector(segmentPageVC:didChangeTopOffset:)]) {
        [_delegate segmentPageVC:self didChangeTopOffset:_constraintHeaderViewHeight.constant];
    }
}

#pragma mark - IBAction

- (void)segmentCtrlDidChange:(UISegmentedControl *)segmentCtrl {
    // 切换视图
    UIViewController *vc = nil;
    if ([_dataSource respondsToSelector:@selector(contentVCInSegmentPageVC:atIndex:)]) {
        vc = [_dataSource contentVCInSegmentPageVC:self atIndex:segmentCtrl.selectedSegmentIndex];
    }
    if (vc) {
        [self _switchContentToVC:vc];
    }
}

#pragma mark - Other

- (void)_switchContentToVC:(UIViewController *)vc {
    // 移除当前的视图
    if (_curContentVC) {
        [_curContentVC willMoveToParentViewController:nil];
        [_curContentVC.view removeFromSuperview];
        [_curContentVC removeFromParentViewController];
        [_curContentVC didMoveToParentViewController:nil];
        
    }
    // 加入新的视图
    vc.automaticallyAdjustsScrollViewInsets = NO;
    [vc willMoveToParentViewController:self];
    [self.view insertSubview:vc.view atIndex:0];
    [self addChildViewController:vc];
    [vc didMoveToParentViewController:self];
    // 因为要使用autoLayout
    if ([vc.view respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        vc.view.preservesSuperviewLayoutMargins = YES;
    }
    vc.view.translatesAutoresizingMaskIntoConstraints = NO;
    // 根据是否有ScrollView来设置约束
    UIScrollView *scrollView = nil;
    if ([_dataSource respondsToSelector:@selector(scrollViewInSegmentPageVC:atIndex:)]) {
        scrollView = [_dataSource scrollViewInSegmentPageVC:self atIndex:_segmentView.segmentCtrl.selectedSegmentIndex];
    }
    if (_curScrollView) {
        [self removeObserverForScrollView:_curScrollView];
    }
    if (scrollView) {
        [scrollView  setContentInset:UIEdgeInsetsMake(_segmentViewMaxTopOffset+_segmentViewHeight, 0, 0, 0)];
        
        [self addObserverForScrollView:scrollView];
        
        _curScrollView = scrollView;
        
        // 设置约束
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
    } else {
        _constraintHeaderViewHeight.constant = _segmentViewMaxTopOffset;
        // 通知偏移发生改变
        if ([_delegate respondsToSelector:@selector(segmentPageVC:didChangeTopOffset:)]) {
            [_delegate segmentPageVC:self didChangeTopOffset:_constraintHeaderViewHeight.constant];
        }
        // 设置约束
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_segmentView attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:vc.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
    }
    // 记录
    _curContentVC = vc;
}

@end
